﻿using UnityEngine;
using UnityEngine.Events;
using UnityEngine.EventSystems;

/// <summary>
/// 检测鼠标双击事件（左键/右键），支持自定义双击间隔和移动容差。
/// </summary>
public class MouseDoubleClick : MonoBehaviour, IPointerDownHandler, IPointerUpHandler, IDragHandler
{
    [System.Serializable]
    public class MouseEvent : UnityEvent
    {
    }

    [System.Serializable]
    public class MouseEventWithData : UnityEvent<PointerEventData>
    {
    }

    public MouseEvent onLeftDoubleClick = new MouseEvent();
    public MouseEventWithData onLeftDoubleClickWithEvent = new MouseEventWithData();

    public MouseEvent onRightDoubleClick = new MouseEvent();
    public MouseEventWithData onRightDoubleClickWithEvent = new MouseEventWithData();

    public MouseEvent onDoubleClick = new MouseEvent();
    public MouseEventWithData onDoubleClickWithEvent = new MouseEventWithData();

    [Tooltip("两次点击之间的最大允许时间（秒），默认为 0.3 秒")]
    public float maxDoubleClickTime = 0.3f;

    [Tooltip("点击时允许的最大移动距离（像素）")] public float maxMoveDistance = 10f;
    private Vector2 firstClickPosition;
    private float firstClickTime = -1f;
    private PointerEventData lastEventData;
    private bool isDragging = false;

    public void OnPointerDown(PointerEventData eventData)
    {
        isDragging = false;
    }

    public void OnPointerUp(PointerEventData eventData)
    {
        if (isDragging)
        {
            ResetClickState();
            return;
        }

        if (firstClickTime <= 0f)
        {
            firstClickTime = Time.unscaledTime;
            firstClickPosition = eventData.position;
            lastEventData = eventData;
        }
        else
        {
            float timeBetweenClicks = Time.unscaledTime - firstClickTime;
            float distance = Vector2.Distance(eventData.position, firstClickPosition);

            if (timeBetweenClicks <= maxDoubleClickTime && distance <= maxMoveDistance)
            {
                if (eventData.button == PointerEventData.InputButton.Left)
                {
                    onLeftDoubleClick.Invoke();
                    onLeftDoubleClickWithEvent.Invoke(eventData);
                }
                else if (eventData.button == PointerEventData.InputButton.Right)
                {
                    onRightDoubleClick.Invoke();
                    onRightDoubleClickWithEvent.Invoke(eventData);
                }

                onDoubleClick.Invoke();
                onDoubleClickWithEvent.Invoke(eventData);
            }

            ResetClickState();
        }
    }

    public void OnDrag(PointerEventData eventData)
    {
        isDragging = true;
    }

    private void ResetClickState()
    {
        firstClickTime = -1f;
        lastEventData = null;
        isDragging = false;
    }

    public void Add(UnityAction action) => onDoubleClick.AddListener(action);
    public void Add(UnityAction<PointerEventData> action) => onDoubleClickWithEvent.AddListener(action);

    public void AddLeft(UnityAction action) => onLeftDoubleClick.AddListener(action);
    public void AddLeft(UnityAction<PointerEventData> action) => onLeftDoubleClickWithEvent.AddListener(action);

    public void AddRight(UnityAction action) => onRightDoubleClick.AddListener(action);
    public void AddRight(UnityAction<PointerEventData> action) => onRightDoubleClickWithEvent.AddListener(action);
}